const fs = require("fs"),
  http = require("http"),
  WebSocket = require("ws"),
  { spawn } = require("child_process");

// [
//   {
//     http_port: 18081, //流数据接收端口号
//     ws_port: 18082,   //ws端口号（流数据转发）
//     camera_ip: "rtsp://账号:密码@IP地址:554/h264/ch1/main/av_stream", //摄像头地址
//   },
// ];
const query = require("./bin/videoUrl.js");
query()
  .then((res) => {
    // 循环列表，接收流数据，创建ws进程
    for (let i = 0; i < res.length; i++) {
      let STREAM_SECRET = i.toString(), //验证流数据接收
        STREAM_PORT = res[i].http_port ,
        WEBSOCKET_PORT = res[i].ws_port ;
      // console.log("STREAM_PORT:" + STREAM_PORT);
      // console.log("WEBSOCKET_PORT:" + WEBSOCKET_PORT);
      // Websocket Server
      let socketServer = new WebSocket.Server({
        port: WEBSOCKET_PORT,
        perMessageDeflate: false,
      });
      socketServer.connectionCount = 0;
      // 有客户端接入时触发
      socketServer.on("connection", function (socket, upgradeReq) {
        socketServer.connectionCount++;
        console.log(
          "New WebSocket Connection: ",
          (upgradeReq || socket.upgradeReq).socket.remoteAddress,
          (upgradeReq || socket.upgradeReq).headers["user-agent"],
          "(" + socketServer.connectionCount + " total)"
        );
        // 当此连接关闭时触发
        socket.on("close", function (code, message) {
          socketServer.connectionCount--;
          console.log(
            "Disconnected WebSocket (" +
              socketServer.connectionCount +
              " total)"
          );
        });
      });
      // 定义broadcast方法，遍历客户端，发送数据
      socketServer.broadcast = function (data) {
        // clients<Set>存储所有连接的客户端
        socketServer.clients.forEach(function each(client) {
          if (client.readyState === WebSocket.OPEN) {
            client.send(data);
          }
        });
      };
      // 创建http对象，从ffmpeg接收MPEG-TS 流数据
      let streamServer = http.createServer(function (request, response) {
        // 提取储存在路径中的密码，并验证
        let params = request.url.substr(1).split("/");
        if (params[0] !== STREAM_SECRET) {
          console.log(
            "Failed Stream Connection: " +
              request.socket.remoteAddress +
              ":" +
              request.socket.remotePort +
              " - wrong secret."
          );
          response.end();
        }
        // 设置超时时间
        response.connection.setTimeout(0);
        console.log(
          "Stream Connected: " +
            request.socket.remoteAddress +
            ":" +
            request.socket.remotePort
        );
        // 获取此路径的数据，并通过websocket转发
        request.on("data", function (data) {
          socketServer.broadcast(data);

          if (request.socket.recording) {
            request.socket.recording.write(data);
          }
        });
        request.on("end", function () {
          console.log("close");
          if (request.socket.recording) {
            request.socket.recording.close();
          }
        });
      });
      // Keep the socket open for streaming
      // 限制解析器等待接收完整HTTP报头的时间
      streamServer.headersTimeout = 0;
      streamServer.listen(STREAM_PORT);

      console.log(
        "Listening for incomming MPEG-TS Stream on http://127.0.0.1:" +
          STREAM_PORT +
          "/<secret>"
      );
      console.log(
        "Awaiting WebSocket connections on ws://127.0.0.1:" +
          WEBSOCKET_PORT +
          "/"
      );
    }
    return res
  })
  .then((res) => {
    for (let i = 0; i < res.length; i++) {

      // 配置ffmpeg命令参数，
      let childProcess = spawn("ffmpeg", [
        "-re",
        "-rtsp_transport",
        "tcp",
        "-i", // 源文件
        res[i].camera_ip,
        "-q",
        "0",
        "-f", 
        "mpegts",
        "-codec:v", // 编解码器名称
        "mpeg1video",
        "-r",
        "20",
        "-b:v",
        "128",
        "-s", // 分辨率
        "1024x768",
        `http://127.0.0.1:${res[i].http_port}/${i}`,
      ]);
      childProcess.stderr.on("data", (data) => {
        console.log(`stderr: ${data}`);
      });
      childProcess.on("close", (code) => {
        console.log(`转码进程${i + 1}退出 with code${code}`);
      });
      console.log(`转码进程${i + 1}启动`);
    }
  });